﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LumenLiquid.Debug;
using LumenLiquid.InGame;
using Microsoft.Xna.Framework.Graphics;

namespace LumenLiquid.Resources
{
    public class Modelmanager
    {
        private struct SModel
        {
            public string Id { get; set; }
            public Model Model { get; set; }

            public SModel(string id = null)
                : this()
            {
                Id = id;
            }
        }


        private Dictionary<string, List<SModel>> _models;

        public Modelmanager()
        {
            DebugHandler.Log("Starting modelmanager...", DebugHandler.EDebugLevel.Code);
            _models = new Dictionary<string, List<SModel>>();
            _models.Add("global", new List<SModel>());
        }

        /// <summary>
        /// Gets a model in the global group
        /// </summary>
        /// <param name="id">The id of the model to load</param>
        /// <returns>The model file</returns>
        /// <remarks>If model doesn't exist, the model will be loaded. The global group cannot be unloaded, so watch out what you put in there.</remarks>
        public Model GetGlobalModel(string id)
        {
            DebugHandler.Log("Getting global model with id \"" + id + "\"");

            SModel model = _models["global"].Find(m => Equals(m.Id, id));

            if (model.Id == null)
            {
                model.Model = Main.Instance.Content.Load<Model>(Path.Content.Models + id);
                model.Id = id;
            }

            if (model.Model == null)
            {
                DebugHandler.Log("Model with id \"" + id + "\" was not found.", DebugHandler.EDebugLevel.Warning);
                return null;
            }

            _models["global"].Add(model);

            return model.Model;
        }

        /// <summary>
        /// Gets a model for the current world
        /// </summary>
        /// <param name="id">The id of the model to load</param>
        /// <returns>The model file</returns>
        /// <remarks>If model doesn't exist, the model will be loaded.</remarks>
        public Model GetWorldModel(string id)
        {
            DebugHandler.Log("Getting world model with id \"" + id + "\"");

            if (!_models.ContainsKey(MainGame.Instance.World))
                _models.Add(MainGame.Instance.World, new List<SModel>());

            SModel model = _models[MainGame.Instance.World].Find(m => Equals(m.Id, id));

            if (model.Id == null)
            {
                model.Model = Main.Instance.Content.Load<Model>(Path.Content.WorldFolder + MainGame.Instance.World + Path.Content.MapModels + id);
                model.Id = id;
            }

            if (model.Model == null)
            {
                DebugHandler.Log("Model with id \"" + id + "\" was not found in world \"" + MainGame.Instance.World + "\"", DebugHandler.EDebugLevel.Warning);
                return null;
            }

            _models[MainGame.Instance.World].Add(model);

            return model.Model;
        }

        /// <summary>
        /// Gets a model from a specific group
        /// </summary>
        /// <param name="id">The id of the model</param>
        /// <param name="group">The group in which the model is placed</param>
        /// <returns>The model file</returns>
        /// <remarks>If model doesn't exist, the model will be loaded.</remarks>
        public Model GetGroupModel(string id, string group)
        {
            DebugHandler.Log("Getting model with id \"" + id + "\"");

            if (!_models.ContainsKey(group))
                _models.Add(group, new List<SModel>());

            SModel model = _models[group].Find(m => Equals(m.Id, id));

            if (model.Id == null)
            {
                model.Model = Main.Instance.Content.Load<Model>(Path.Content.Models + id);
                model.Id = id;
            }

            if (model.Model == null)
            {
                DebugHandler.Log("Model with id \"" + id + "\" was not found.", DebugHandler.EDebugLevel.Warning);
                return null;
            }

            _models[group].Add(model);

            return model.Model;
        }

        /// <summary>
        /// Unloads a whole group or world
        /// </summary>
        /// <param name="group">The group or world to unload</param>
        /// <remarks>Group global cannot be unloaded</remarks>
        public void UnloadGroup(string group)
        {
            if (!Equals(group, "global") && group != null)
            {
                DebugHandler.Log("Unloading model group \"" + group + "\"");
                _models.Remove(group);
            }
        }
    }
}
